home *** CD-ROM | disk | FTP | other *** search
- /* enemy.c */
-
- #include <stdio.h>
- #include <xsp2lib.h>
-
- #include "main.h"
- #include "player.h"
- #include "shot.h"
- #include "enemy.h"
-
- #define ENEMY_MAX 32 /* 敵最大数 */
-
- static ENEMY enemy[ENEMY_MAX]; /* ワーク */
- static ENEMY *enemy_top, /* 使用中のワークのリスト */
- *enemy_null_top, /* 空のワークのリスト */
- *enemy_end; /* 使用中ワークのリストの末尾 */
-
-
- /* 関数プロトタイプ宣言 */
- void EnemyAllocA (ENEMY *);
- int EnemyMoveA (ENEMY *);
- void EnemyAllocB (ENEMY *);
- int EnemyMoveB (ENEMY *);
-
-
- /* 初期化関数へのポインタの配列 */
- typedef void (*enemy_alloc) (ENEMY *);
- enemy_alloc EnemyAllocFunc[] =
- {
- EnemyAllocA,
- EnemyAllocB,
- };
-
- /* 移動関数へのポインタの配列 */
- typedef int (*enemy_move) (ENEMY *);
- enemy_move EnemyMoveFunc[] =
- {
- EnemyMoveA,
- EnemyMoveB,
- };
-
-
- /* タイプAの敵の初期化ルーチン */
- void EnemyAllocA (ENEMY * p)
- {
- p->pt = obj_zako02 + 15;
- p->info = 0x0700 | PRIORITY_ZAKO; /* 数値を決めうちして入れるのはよくない */
- p->hit_sx = 12; /* 自機ショットに対する当たり判定 */
- p->hit_sy = 12;
- p->hp = 1; /* 耐久力 */
- p->damage = 0;
- }
-
- /* タイプAの敵の移動ルーチン */
- /* 返り値:非0なら消去 */
- int EnemyMoveA (ENEMY * p)
- {
- /* 敵をくるくる回すアニメーション */
- p->pt--;
- if (p->pt < obj_zako02)
- p->pt = obj_zako02 + 15;
-
- /* X座標を自機に近づける */
- if (p->lx > player->lx)
- p->lx -= 32768;
- else
- p->lx += 32768;
-
- p->ly += 2 * 65536;
-
- /* 上位ワード(固定整数部)だけ取り出す */
- p->x = p->lx >> 16;
- p->y = p->ly >> 16;
-
- if (p->y > 256 + 32)
- return (-1); /* Y座標が 256+32 以上なら消去 */
-
- /* もし前回ダメージを受けたなら */
- if (p->damage) {
- p->hp -= p->damage;
- p->damage = 0;
- if (p->hp <= 0)
- return (-1); /* 耐久力が0以下なら消去 */
- }
- xobj_set_st (p); /* 表示 */
-
- return (0);
- }
-
-
- /* タイプBの敵の初期化ルーチン */
- void EnemyAllocB (ENEMY * p)
- {
- p->pt = obj_zako02;
- p->info = 0x0800 | PRIORITY_ZAKO; /* 数値を決めうちして入れるのはよくない */
- p->hit_sx = 12; /* 自機ショットに対する当たり判定 */
- p->hit_sy = 12;
- p->hp = 2; /* 耐久力 */
- p->damage = 0;
- }
-
- /* タイプBの敵の移動ルーチン */
- /* 返り値:非0なら消去 */
- int EnemyMoveB (ENEMY * p)
- {
- /* 敵をくるくる回すアニメーション */
- p->pt++;
- if (p->pt > obj_zako02 + 15)
- p->pt = obj_zako02;
-
-
- /* X座標を自機に近づける */
- if (p->lx > player->lx)
- p->lx -= 32768;
- else
- p->lx += 32768;
-
- p->ly += 2 * 65536;
-
- /* 上位ワード(固定整数部)だけ取り出す */
- p->x = p->lx >> 16;
- p->y = p->ly >> 16;
-
- if (p->y > 256 + 32)
- return (-1); /* Y座標が 256+32 以上なら消去 */
-
- /* もし前回ダメージを受けたなら */
- if (p->damage) {
- p->hp -= p->damage;
- p->damage = 0;
- if (p->hp <= 0)
- return (-1); /* 耐久力が0以下なら消去 */
- }
- xobj_set_st (p); /* 表示 */
- return (0);
- }
-
-
-
- /* ゲーム開始時に呼ばれる */
- void EnemyInit (void)
- {
- int i;
-
- /* リストをつなげる */
- enemy_top = NULL;
- enemy_end = NULL;
- enemy_null_top = enemy;
- for (i = 0; i < ENEMY_MAX; i++)
- enemy[i].next = &enemy[i + 1];
-
- enemy[ENEMY_MAX - 1].next = NULL;
- }
-
-
-
- /* 敵出現時に呼ばれる */
- void EnemyAlloc (short type, signed short x, signed short y)
- {
- ENEMY *p;
-
- if (enemy_null_top == NULL)
- return; /* 空きのワークがない(キャラクターオーバー) */
-
- /* リストの末尾に新しいノードを追加(他とは違うので注意) */
- p = enemy_null_top;
- enemy_null_top = p->next;
- if (enemy_top == NULL)
- enemy_top = p;
- else
- enemy_end->next = p;
- p->next = NULL;
- enemy_end = p;
-
- p->type = type;
- p->lx = x << 16;
- p->ly = y << 16;
-
- /* 関数へのポインタを使って分岐 */
- /* type が 0 なら EnemyAllocA() が、1 なら EnemyAllocB() が実行される */
- EnemyAllocFunc[p->type] (p);
-
- return;
- }
-
-
-
- /* 垂直同期ごとに呼ばれる */
- void EnemyMove (void)
- {
- ENEMY *p, *q;
-
- p = enemy_top; /* 現在注目しているワーク */
- q = NULL; /* 1つ前のワーク(ワーク削除時に必要) */
- while (p != NULL) {
- /* 敵キャラの移動ルーチン */
-
- /* 関数へのポインタを使って分岐 */
- /* type が 0 なら EnemyMoveA() が、1 なら EnemyMoveB() が実行される */
-
- if (EnemyMoveFunc[p->type] (p)) { /* 返り値が非0なら消去 */
- if (q == NULL) { /* リストの一番最初を削除 */
- enemy_top = p->next;
- p->next = enemy_null_top;
- enemy_null_top = p;
- q = NULL;
- p = enemy_top;
- } else {
- if (p == enemy_end) { /* リストの一番最後を削除 */
- q->next = NULL;
- enemy_end = q;
- p->next = enemy_null_top;
- enemy_null_top = p;
- p = q->next;
- } else {
- q->next = p->next;
- p->next = enemy_null_top;
- enemy_null_top = p;
- p = q->next;
- }
- }
- } else {
- /* 敵キャラを消去しない場合 */
- SHOT *p2 = shot_top; /* 現在注目しているショットのワーク */
-
- /* ショットとの当たり判定 */
- while (p2 != NULL) {
- if ((p->x - p->hit_sx <= p2->x + p2->hit_x)
- && (p->x + p->hit_sx >= p2->x - p2->hit_x)
- && (p->y - p->hit_sy <= p2->y + p2->hit_y)
- && (p->y + p->hit_sy >= p2->y - p2->hit_y)) {
- /* ショットが当たった */
- p->damage++; /* 敵キャラにダメージを与える */
- p2->damage = !0; /* 自機ショットに当たった事を知らせる */
- }
- p2 = p2->next;
- }
- q = p;
- p = p->next;
- }
- }
- }
-